//go:build wireinject

package main

import (
	"forum/internal/adapter/driven/web"
	cache2 "forum/internal/adapter/driving/cache"
	"forum/internal/adapter/driving/dao"
	"forum/internal/adapter/driving/event/article"
	"forum/internal/adapter/driving/repo"
	"forum/internal/application"
	"forum/internal/domain/cache"
	"forum/internal/domain/event"
	article2 "forum/internal/domain/event/article"
	repo2 "forum/internal/domain/repo"
	cache4 "forum/intr/adapter/driving/cache"
	dao2 "forum/intr/adapter/driving/dao"
	repo4 "forum/intr/adapter/driving/repo"
	application2 "forum/intr/application"
	cache3 "forum/intr/domain/cache"
	repo3 "forum/intr/domain/repo"
	"forum/ioc"
)
import "github.com/google/wire"

func InitWebServer() *App {
	wire.Build(
		//adapter driving
		ioc.InitMysqlDB, ioc.InitRedisCache,
		//adapter driven
		//repo
		wire.NewSet(
			repo.NewUserRepositoryImp, repo.NewArticleRepositoryImp, repo4.NewInteractiveRepositoryImp,
			wire.Bind(new(repo2.ArticleRepository),
				new(*repo.ArticleRepositoryImp)),
			wire.Bind(new(repo2.UserRepository),
				new(*repo.UserRepositoryImp)),
			wire.Bind(new(repo3.InteractiveRepository),
				new(*repo4.InteractiveRepositoryImp))),
		//dao

		wire.NewSet(dao.NewUserMysqlDao, dao.NewArticleSQLDao, dao2.NewInteractiveMysqlDao,
			wire.Bind(new(dao.UserDao),
				new(*dao.UserMysqlDao)),
			wire.Bind(new(dao.ArticleDao),
				new(*dao.ArticleSQLDao)),
			wire.Bind(new(dao2.InteractiveDao),
				new(*dao2.InteractiveMysqlDao)),
		),
		//cache
		wire.NewSet(
			cache2.NewArticleRedisCache, cache4.NewInteractiveRedisCache,
			wire.Bind(new(cache.ArticleCache),
				new(*cache2.ArticleRedisCache)),
			wire.Bind(new(cache3.InteractiveCache),
				new(*cache4.InteractiveRedisCache)),
		),
		//MQ
		wire.NewSet(
			article.NewSaramaArticleProducer, article.NewBatchReadCntConsumer,
			wire.Bind(new(article2.Producer), new(*article.SaramaArticleProducer)),
			wire.Bind(new(event.Consumer), new(*article.BatchReadCntConsumer)),
		),
		//service

		wire.NewSet(application.NewUserServiceImp,
			application.NewJwtServiceImp,
			application.NewArticleServiceImp,
			application2.NewInteractiveServiceImp,
			wire.Bind(new(application.UserService),
				new(*application.UserServiceImp)),
			wire.Bind(new(application.JwtService),
				new(*application.JwtServiceImp)),
			wire.Bind(new(application.ArticleService),
				new(*application.ArticleServiceImp)),
			wire.Bind(new(application2.InteractiveService),
				new(*application2.InteractiveServiceImp)),
		),
		//handler
		web.NewUserHandler, web.NewArticleHandler,
		ioc.InitWeb, ioc.InitSaramaClient,
		ioc.InitProducer,
		ioc.InitConsumers,
		wire.Struct(new(App), "*"),
	)
	return new(App)

}
